﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using GameBase;

namespace GalaxyPresident
{
    public abstract class BBB : UniveralObject
    {
        protected Team teamOwner = null;
        protected DetailPlanetView viewLayer;

        protected List<Block> _blocks = new List<Block>();
        protected int blockCount;
        protected double anglePerBlock;

        public DetailPlanetView ViewLayer
        {
            get { return viewLayer; }
            set { viewLayer = value; }
        }

        public List<Block> Blocks
        {
            get { return _blocks; }
            set { _blocks = value; }
        }

        public int BlockCount
        {
            get { return blockCount; }
        }

        public BBB(string strImage, float diameter, float velocity, Orbit orbit)
            : base(strImage, diameter, velocity, orbit)
        {
            blockCount = (int)(Constant.scaleDetailPlanet * diameter * Math.PI / Constant.sizeBlock);
            anglePerBlock = -2 * Math.PI / blockCount;

            initBlock();
            
        }

        protected virtual void initBlock()
        {
            
        }
        public void ClearAtBlock(int blockIndex)
        {
            if (viewLayer != null && _blocks[blockIndex].Entity!= null)
                viewLayer.RemoveChild(_blocks[blockIndex].Entity);
            _blocks[blockIndex].Entity = null;
            _blocks[blockIndex].IsJustDestroy = true;
            
        }

        public void addNewEntityAtBlock(PlanetEntity planetEntity, int blockIndex)
        {
            if (isAvailableAddNewEntityAtBlock(planetEntity, blockIndex))
            {
                internalAddNewEntityAtBlock(planetEntity, blockIndex);
                planetEntity.updatePlanetOwnerResources();

                if (planetEntity.GetType() == typeof(Capital))
                {
                    ((Capital)planetEntity).setCompletelyTeamOwner();

                    teamOwner = planetEntity.PlanetOwner.TeamOwner;
                    teamOwner.Planets.Add(planetEntity.PlanetOwner);
                }
            }
        }

        public void autoAddNewEntityAtBlock(PlanetEntity planetEntity, int blockIndex)
        {
            if(isAvailableAddNewEntityAtBlock(planetEntity, blockIndex))
                internalAddNewEntityAtBlock(planetEntity, blockIndex);
        }

        private bool isAvailableAddNewEntityAtBlock(PlanetEntity planetEntity, int blockIndex)
        {
            if (blockIndex >= _blocks.Count || _blocks[blockIndex].Entity != null)
                return false;

            if (planetEntity.isCommonEntity() && (_blocks[blockIndex].GetType() == typeof(DeathBlock)))
                return false;

            //if (this.GetType() == typeof(Moon))
            //    return false;

            return true;
        }

        private void internalAddNewEntityAtBlock(PlanetEntity planetEntity, int blockIndex)
        {
            _blocks[blockIndex].Entity = planetEntity;

            if (viewLayer != null)
                viewLayer.AddChild(planetEntity);

            planetEntity.Height = Constant.scaleDetailPlanet * Diameter / 2 - 20 - (float)Constant.random.NextDouble() * 5;
            planetEntity.Position = /*position + */planetEntity.Height * new Vector2((float)Math.Cos(blockIndex * anglePerBlock - Math.PI / 2), (float)Math.Sin(blockIndex * anglePerBlock - Math.PI / 2));
            planetEntity.Rotate = (float)(blockIndex * anglePerBlock);

            planetEntity.startUpdatePlanetInfo();

            Vector2 temp1 = getPositionAtBlockIndex(0);
            Vector2 temp2 = getPositionAtBlockIndex(1);
            planetEntity.Scale = (temp1 - temp2).Length() / planetEntity.ListSprites[0].Width;

            _blocks[blockIndex].Entity.BlockIndex = blockIndex;
        }
        public Vector2 GetBlockPosition(int blockIndex)
        {
            float height = Constant.scaleDetailPlanet * Diameter / 2 - 10 ;
            return height * new Vector2((float)Math.Cos(blockIndex * anglePerBlock - Math.PI / 2),
                (float)Math.Sin(blockIndex * anglePerBlock - Math.PI / 2));
        }
        public float GetBlockRotation(int blockIndex)
        {
            return (float)(blockIndex * anglePerBlock);
        }
        public bool IsEmptyBlock(int blockIndex)
        {
            return _blocks[blockIndex].Entity == null;
        }
        protected Vector2 getPositionAtBlockIndex(int blockIndex)
        {
            if (blockIndex < 0 || blockIndex >= blockCount)
                return Vector2.Zero;

            Vector2 result = Vector2.Zero;
            double angleOfPerBlock = Math.PI * 2 / blockCount;

            result.X = (float)(Constant.scaleDetailPlanet * Diameter / 2 * Math.Cos(angleOfPerBlock * blockIndex));
            result.Y = (float)(Constant.scaleDetailPlanet * Diameter / 2 * Math.Sin(angleOfPerBlock * blockIndex));

            return result;
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            for (int i = 0; i < _blocks.Count; i++)
            {
                _blocks[i].Update(gameTime);
            }
        }

        public override void UpdateInfo(GameTime gameTime)
        {
            base.UpdateInfo(gameTime);

            for (int i = 0; i < _blocks.Count; i++)
            {
                _blocks[i].UpdateInfo(gameTime);
            }
            viewLayer.UpdateInfo(gameTime);
        }
    }
}
